package com.ray.validate.support.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author bo shen
 * @Description: 属性操作
 * @Class: PropertyUtils
 * @Package tf56.antcolonyums.validate.support.utils
 * @date 2019/11/19 15:46
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
public class PropertyUtils {

    public static void setProperty(Object bean, String name, Object value) {
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor prop : properties) {
                String key = prop.getName();
                if(key.equals(name)){
                    Method setMethod = prop.getWriteMethod();
                    setMethod.invoke(bean, value);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public static String getProperty(Object bean, String name) {
        String returnO = null;
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor prop : properties) {
                String key = prop.getName();
                if(key.equals(name)){
                    Method getMethod = prop.getReadMethod();
                    Object o = getMethod.invoke(bean);
                   return o == null ? null: String.valueOf(o);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
        return returnO;
    }

    /**
     * 获取对象属性
     * @param bean
     * @param name
     * @return
     */
    public static Object getObjectProperty(Object bean, String name) {
        Object returnO = null;
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor prop : properties) {
                String key = prop.getName();
                if(key.equals(name)){
                    Method getMethod = prop.getReadMethod();
                    Object o = getMethod.invoke(bean);
                    return o;
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
        return returnO;
    }

    public static void witerProperty(Object bean, String name, Object value) {
        try {
            final Class<?> cls = bean.getClass();
            final Field field = getDeclaredField(cls, name, true);
            field.set(bean, value);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public static Object readProperty(Object bean, String name) {
        Object returnO = null;
        try {
            final Class<?> cls = bean.getClass();
            final Field field = getDeclaredField(cls, name, true);
            returnO =  field.get(bean);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
        return returnO;
    }

    public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
        Assert.isTrue(cls != null, "The class must not be null");
        Assert.hasLength(fieldName, "The field name must not be blank/empty");
        try {
            final Field field = cls.getDeclaredField(fieldName);
            if (forceAccess) {
                field.setAccessible(true);
            }
            return field;
        } catch (final NoSuchFieldException e) {
            // ignore
        }
        return null;
    }
}
